import config from '@/config'
import Taro, { getCurrentPages, setStorageSync } from '@tarojs/taro'
import store from '@/store'
import dayjs from 'dayjs'
import weappJwt from './weapp-jwt.js'

// 给个时间戳，不用打包手动改
const timestamp = dayjs().format('YYYYMMDDHHmm')

const PAGE_LEVEL_LIMIT = 10

/**
 * 防重复点击函数
 * @param {number} timeLength - 防重复点击的时间间隔，单位为毫秒，默认为1000毫秒
 * @returns {Function} - 返回一个装饰器函数
 */
export function preventDouble(timeLength = 1000) {
  return function (originalFunction) {
    let lastClickTime = 0
    return function (...args) {
      const now = Date.now()
      if (now - lastClickTime < timeLength) {
        return
      }
      lastClickTime = now
      return originalFunction.apply(this, args)
    }
  }
}

/**
 *
 * @param {*} url
 * @param {*} params
 * @param {*} options method = navigateTo | 'redirectTo' | 'navigateToByForce'
 */
export function gotoPage(url, params, options) {
  const pages = Taro.getCurrentPages()
  let method = options?.method || 'navigateTo'
  if (url) {
    if (method === 'navigateTo' && pages.length >= PAGE_LEVEL_LIMIT - 3) {
      method = 'redirectTo'
    }
    if (method === 'navigateToByForce') {
      method = 'navigateTo'
    }
    if (method === 'navigateTo' && pages.length === PAGE_LEVEL_LIMIT) {
      method = 'redirectTo'
    }
    const extend = objToParam(params || {})
    if (extend.length) {
      url += (url.indexOf('?') > -1 ? '&' : '?') + extend
    }
    Taro[method]({ url })
  } else {
    Taro[options?.method ? method : 'redirectTo']({ url: '/pages/classAssistant/home/index' })
  }
}
export function goView(url, params = {}, redirect = false) {
  return gotoPage(url, params || {}, redirect ? { method: 'redirectTo' } : {})
}
// 防抖函数
export function debounce(fn, wait, immediate) {
  let timer
  return function () {
    if (timer) clearTimeout(timer)
    if (immediate) {
      // 如果已经执行过，不再执行
      const callNow = !timer
      timer = setTimeout(() => {
        timer = null
      }, wait)
      if (callNow) {
        fn.apply(this, arguments)
      }
    } else {
      timer = setTimeout(() => {
        fn.apply(this, arguments)
      }, wait)
    }
  }
}
/**
 * 获取值类型
 * @param {any} 需要获取类型的值
 * @return {string} 返回具体类型，例如：Object、Array
 **/
export function getType(item) {
  return Object.prototype.toString.call(item)?.slice(8, -1)
}

/**
 * 将对象拼接成url参数，
 * @return {string} 不带？号的字符串
 **/
export function objToParam(data) {
  let url = ''
  for (const k in data) {
    const value = data[k] !== undefined ? data[k] : ''
    if (k !== '$taroTimestamp') {
      // 去除taro参数
      url += '&' + k + '=' + value
    }
  }
  return url ? url.substring(1) : ''
}
/**
 * 传入小程序链接、路由传参对象，自动拼接并且跳转小程序页面
 * @params{string} url 跳转目标链接
 * @params{object} obj 路由传参对象
 * @params{string} type 跳转方式，默认navigateTo、reLaunch、redirectTo
 */
export function goPage(url, obj, type = 'navigateTo') {
  if (!url) return
  const params = objToParam(obj)
  Taro[type]({ url: `${url}?${params}` })
}

/***
 * @params{v1、v2版本号}
 * @return {0版本相同、-1前小于后，1前大于后}
 ****/
export function compareVersion(v1, v2) {
  v1 = v1.split('.')
  v2 = v2.split('.')
  const len = Math.max(v1.length, v2.length)

  while (v1.length < len) {
    v1.push('0')
  }
  while (v2.length < len) {
    v2.push('0')
  }

  for (let i = 0; i < len; i++) {
    const num1 = parseInt(v1[i])
    const num2 = parseInt(v2[i])

    if (num1 > num2) {
      return 1
    } else if (num1 < num2) {
      return -1
    }
  }

  return 0
}

/**
 * 获取时间
 * @param {*} date
 * @returns {string}
 */
export function createDate(date) {
  if (date) {
    if (typeof date === 'string') date = date.replace(/-/g, '/').replace(/\..*/g, '')
    return new Date(date)
  }
  return new Date()
}

/**
 * 解析16进制编码含有中文
 **/
export function deCodeUrl(h) {
  return fromHex(fromUnicode(h))
}
// 编码16进制含有中文
export function enCodeUrl(s) {
  return toHex(toUnicode(s))
}
// 解析16进制编码
export function fromHex(h) {
  if (h != null && h !== undefined && typeof h === 'string' && h.length > 0) {
    let s = ''
    for (let i = 0; i < h.length; i += 2) {
      s += String.fromCharCode(parseInt(h.substr(i, 2), 16))
    }
    return s
  }
  return h
}
// Unicode转中文
export function fromUnicode(str) {
  if (str != null && str !== undefined && typeof str === 'string' && str.length > 0) {
    let ignore = 0

    return str
      .split('')
      .map(function (value, index, array) {
        if (ignore-- > 0) {
          return ''
        }
        if (value === '\\') {
          if (array[index + 1] === 'u') {
            ignore = 5
            return String.fromCodePoint('0x' + array.slice(index + 2, index + 6).join(''))
          }
        }
        return value
      })
      .join('')
  }
  return str
}

// 转16进制编码
export function toHex(s) {
  if (s != null && s !== undefined && typeof s === 'string' && s.length > 0) {
    // utf8 to latin1
    let h = ''
    for (let i = 0; i < s.length; i++) {
      h += s.charCodeAt(i).toString(16)
    }
    return h
  }
  return s
}

// 中文转码Unicode
export function toUnicode(str) {
  if (str != null && str !== undefined && typeof str === 'string' && str.length > 0) {
    return str
      .split('')
      .map(function (value) {
        const temp = value.codePointAt(0).toString(16).toUpperCase()
        if (temp.length > 2) {
          return '\\u' + temp
        }
        return value
      })
      .join('')
  }
  return str
}

/**
 * 将rpx转成px
 */
export function rpxTopx(rpx) {
  const deviceWidth = Taro.getSystemInfoSync().windowWidth // 获取设备屏幕宽度
  const px = (deviceWidth / 750) * Number(rpx)
  return Math.floor(px)
}

/**
 * 获取cdn图片url
 * @param {string} fileName 文件名
 * @param {string} path 所在目录
 * @returns string
 */
export function getImgUrl(fileName, path = 'home') {
  return `${config.baseUrl.fileUrl}/${path}/${fileName}?t=${timestamp}`
}
/**
 * 获取cdn背景图片样式
 */
export function getBgImgStyle(fileName, path = 'home', style = 'no-repeat center / 100%;') {
  return `background: url(${config.baseUrl.fileUrl}/${path}/${fileName}?t=${timestamp}) ${style}`
}
/**
 * 页面回退
 */
export function goBack(delta = 1) {
  const pages = Taro.getCurrentPages()
  if (pages.length >= 2) {
    Taro.navigateBack({
      delta
    })
  } else {
    Taro.redirectTo({
      url: '/pages/home/index'
    })
  }
}
/**
 * 日期格式化，今年返回月日，否则返回年月日
 * @param {string} time 日期
 * @returns string 时间
 */
export function timeConvert(time, type = 1) {
  if (!time) return time
  if (type === 1) {
    if (dayjs(time).year() === dayjs().year()) {
      return dayjs(time).format('MM月DD日')
    } else {
      return dayjs(time).format('YYYY年MM月DD日')
    }
  } else {
    return dayjs(time).format('YYYY年MM月DD日')
  }
}

/**
 *
 * @param {Object} data
 * @param {Object} pageIndex 同上 默认 2 上一个页面
 * @param {Object} cb 回调函数
 * @returns
 */
export function setPageData({ data, pageIndex = 2, cb }) {
  const pages = getCurrentPages()
  if (pages.length < pageIndex) return console.log('页面栈获取错误')
  const pageObj = pages[pages.length - pageIndex]
  pageObj.setData(data)
  cb && cb()
}
/**
 *
 * @param {number} pageIndex 1 当前页面  2上一个页面 3...以此类推  默认1
 * @returns {Object} data 当前页面存储的数据 currentPage 当前页面 pages所有页面栈
 */
export function getPageData(pageIndex = 1) {
  const pages = getCurrentPages()
  if (pages.length < pageIndex) {
    return false
  }
  const currentPage = pages[pages.length - pageIndex]
  return {
    data: currentPage.data,
    currentPage,
    pages
  }
}

export function withResolvers() {
  const out = {}
  out.promise = new Promise((_resolve, _reject) => {
    out.resolve = function () {
      out.promise.state = 'resolved'
      _resolve.apply(out.promise, arguments)
    }
    out.reject = function () {
      out.promise.state = 'rejected'
      _reject.apply(out.promise, arguments)
    }
  })
  return out
}
/**
 * 订阅引导图，cdn图片 style样式设置方法
 */
export function setBackGroundStyle(url, fileName, style = 'no-repeat center / 100%;') {
  return `background: url(${config.baseUrl.appletCdn}/${fileName}/${url}?t=20231214) ${
    style || 'no-repeat center / 100%;'
  }`
}
export function getParamsUrl(u) {
  const obj = {}
  const uQuery = u.split('?')
  if (uQuery.length > 1) {
    const arr = uQuery[1].length === 0 ? [] : uQuery[1].split('&')
    // 获取参数转换为object
    for (let i = 0; i < arr.length; i++) {
      arr[i] = arr[i].split('=')
      obj[arr[i][0]] = arr[i][1]
    }
  }
  return {
    url: uQuery[0],
    ...obj
  }
}
/**
 *@prams {String:url, String:key}
 *@return value
 **/
export function getUrlPrams(url, name) {
  const reg = new RegExp('(^|&)' + name + '=([^&]*)(&|$)', 'i')
  const r = url.slice(url.indexOf('?')).substr(1)?.match(reg)
  if (r != null) {
    return decodeURIComponent(r[2])
  } else {
    return null
  }
}

export function paramUrl(data) {
  let url = ''
  for (const k in data) {
    const value = data[k] !== undefined ? data[k] : ''
    url += '&' + k + '=' + value
  }
  return url ? url.substring(1) : ''
}
// 统一清除用户信息
export function delLoginInfoStore() {
  store.user.setToken('')
  store.user.setAccessTokenExpire('')
  store.user.setUserInfo({})
}

/**
 * 文件分享或下载
 * 手机端是分享文件
 * PC端是下载文件
 * trueFileUrl: http文件真实链接，下载失败复制链接自行下载
 */
export function onFileShareOrSave(filePath, fileName, callBack, trueFileUrl) {
  if (filePath) {
    // 有文件地址 则进行下一步
    const { platform } = getWxApi('getDeviceInfo')
    if (['android', 'ios'].includes(platform)) {
      // 手机端
      Taro.shareFileMessage({
        filePath,
        fileName: fileName || '',
        success() {
          callBack && callBack('success')
        },
        fail() {
          Taro.showToast({
            title: '分享文件失败,请重试!',
            icon: 'none'
          })
          callBack && callBack('fail')
        }
      })
    } else if (['windows', 'mac'].includes(platform)) {
      // PC端
      const fs = Taro.getFileSystemManager()
      fs.copyFile({
        srcPath: filePath,
        destPath: `${Taro.env.USER_DATA_PATH}/${fileName}`,
        success: function () {
          Taro.saveFileToDisk({
            filePath: `${Taro.env.USER_DATA_PATH}/${fileName}`,
            success: function () {
              Taro.showToast({ title: '下载成功', icon: 'none' })
            },
            fail: function () {
              Taro.setClipboardData({
                data: trueFileUrl || filePath,
                success: function () {
                  Taro.showToast({ title: '已复制下载链接', icon: 'none' })
                }
              })
            }
          })
        }
      })
      // Taro.saveFileToDisk({
      //   filePath,
      //   success() {
      //     callBack && callBack('success')
      //   },
      //   fail() {
      //     Taro.setClipboardData({
      //       data: trueFileUrl || filePath,
      //       success: function () {
      //         Taro.showToast({ title: '已复制下载链接', icon: 'none' })
      //       }
      //     })
      //     callBack && callBack('fail')
      //   }
      // })
    } else {
      // 开发者工具
      Taro.showToast({
        title: '开发者工具不支持分享和下载',
        icon: 'none'
      })
      callBack && callBack('fail')
    }
  } else {
    // 文件地址有误
    Taro.showToast({
      title: '文件有误,请重启小程序或联系客服人员!',
      icon: 'none'
    })
    callBack && callBack('fail')
  }
}

/**
 * 检查文件类型
 * @param {string} url 文件地址
 * @returns {object} 包含文件类型和文件地址的对象
 */

export function changeFileType(url, coverImg = '', isUserFile = true, fileSort = 'AttachFile') {
  if (!url || !url.includes('.')) {
    return {
      attachFileUrl: url,
      fileSort,
      attachFileType: '',
      attachFileCoverimg: coverImg,
      isUserFile
    }
  }
  const extensions = new Map([
    ['Image', ['jpeg', 'jpg', 'gif', 'png']],
    ['Video', ['mp4', 'mov', 'm4v', 'avi']],
    ['PPT', ['ppt', 'pptx']],
    ['PDF', ['pdf']],
    ['Word', ['doc', 'docx']]
  ])

  let extension
  const match = url?.match(/\.([^.]+)$/)
  if (match) {
    extension = match[1].toLowerCase()
  } else {
    return {
      attachFileUrl: url,
      fileSort,
      attachFileType: '',
      attachFileCoverimg: coverImg,
      isUserFile
    }
  }
  for (const [type, exts] of extensions) {
    if (exts.includes(extension)) {
      return {
        attachFileUrl: url,
        fileSort,
        attachFileType: type,
        attachFileCoverimg: coverImg,
        isUserFile
      }
    }
  }

  return {
    attachFileUrl: url,
    fileSort,
    attachFileType: '',
    attachFileCoverimg: coverImg,
    isUserFile
  }
}
export function checkFileType(url) {
  const allowedExtensions = [
    ...['jpeg', 'jpg', 'gif', 'png'],
    ...['mp4', 'mov', 'm4v', 'avi'],
    ...['ppt', 'pptx'],
    ...['pdf'],
    ...['doc', 'docx']
  ]

  const fileExtension = url.split('.').pop().toLowerCase()

  return !!allowedExtensions.includes(fileExtension)
}
export function checkImageType(url) {
  const allowedExtensions = [...['jpeg', 'jpg', 'gif', 'png']]
  const fileExtension = url.split('.').pop().toLowerCase()
  return !!allowedExtensions.includes(fileExtension)
}
export function parseToken(token) {
  const base64Url = token && token.split('.')[1]
  const base64 = base64Url.replace('-', '+').replace('_', '/')
  const dataJWT = JSON.parse(weappJwt?.atob ? weappJwt.atob(base64) : '{}')
  return dataJWT
}

// 处理数字格式化 按照千位逗号分割
export function formatNumberWithCommas(number) {
  // 将数字转换为字符串并使用正则表达式进行格式化
  return number?.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',')
}
export function getWxApi(fn) {
  if (Taro[fn]) {
    return Taro[fn]()
  } else {
    if (Taro.getSystemInfoSync) {
      return Taro.getSystemInfoSync()
    } else {
      return {}
    }
  }
}
